package it.unibo.refolding.pico.transformers;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import com.google.common.base.Preconditions;

public class ByteArray2ShortArrayStrategyInt implements Transformer {
  private final ByteOrder byteOrder;
  private final double encoderScalingOffset;
  private final double encoderScalingMultiplier;
  /**
   * Mask of the conversion target type.
   */
  private final long mask;

  public ByteArray2ShortArrayStrategyInt(ByteOrder byteOrder, double encoderScalingOffset,
    double encoderScalingMultiplier, boolean signed) {
    this.byteOrder = byteOrder;
    this.encoderScalingOffset = encoderScalingOffset;
    this.encoderScalingMultiplier = encoderScalingMultiplier;
    this.mask = signed ? -1L : Long.valueOf(0xFFFFFFFFL);
  }

  @Override
  public short[] transform(byte[] input, double factor) {
    Preconditions.checkArgument((input.length & 3) == 0);
    ByteBuffer bb = ByteBuffer.wrap(input);
    bb.order(byteOrder);
    IntBuffer sb = bb.asIntBuffer();
    int len = input.length >> 2;
    short[] s = new short[len];
    for (int i = 0; i < len; ++i) {
      int a = sb.get();
      long x = a & mask;
      double d = (encoderScalingOffset + x * encoderScalingMultiplier) / factor;
      Preconditions.checkArgument(Math.abs(d) <= Short.MAX_VALUE, d);
      s[i] = (short) d;
    }
    assert !sb.hasRemaining();
    return s;
  }
}
